home *** CD-ROM | disk | FTP | other *** search
/ Personal Computer World 2005 October / PCWOCT05.iso / Software / FromTheMag / XAMPP 1.4.14 / xampp-win32-1.4.14-installer.exe / xampp / php / pear / HTML / Table.php < prev    next >
PHP Script  |  2004-03-24  |  26KB  |  700 lines

  1. <?php
  2. /* vim: set expandtab tabstop=4 shiftwidth=4: */
  3. // +----------------------------------------------------------------------+
  4. // | PHP Version 4                                                        |
  5. // +----------------------------------------------------------------------+
  6. // | Copyright (c) 1997, 1998, 1999, 2000, 2001 The PHP Group             |
  7. // +----------------------------------------------------------------------+
  8. // | This source file is subject to version 2.0 of the PHP license,       |
  9. // | that is bundled with this package in the file LICENSE, and is        |
  10. // | available at through the world-wide-web at                           |
  11. // | http://www.php.net/license/2_02.txt.                                 |
  12. // | If you did not receive a copy of the PHP license and are unable to   |
  13. // | obtain it through the world-wide-web, please send a note to          |
  14. // | license@php.net so we can mail you a copy immediately.               |
  15. // +----------------------------------------------------------------------+
  16. // | Authors: Adam Daniel <adaniel1@eesus.jnj.com>                        |
  17. // |          Bertrand Mansion <bmansion@mamasam.com>                     |
  18. // +----------------------------------------------------------------------+
  19. //
  20. // $Id: Table.php,v 1.12 2003/05/20 10:48:03 mansion Exp $
  21.  
  22. require_once "PEAR.php";
  23. require_once "HTML/Common.php";
  24.  
  25. /**
  26.  * Builds an HTML table
  27.  * @author        Adam Daniel <adaniel1@eesus.jnj.com>
  28.  * @author        Bertrand Mansion <bmansion@mamasam.com>
  29.  * @version       1.7
  30.  * @since         PHP 4.0.3pl1
  31.  */
  32. class HTML_Table extends HTML_Common {
  33.  
  34.     /**
  35.      * Automatically adds a new row or column if a given row or column index does not exist
  36.      * @var    bool
  37.      * @access private
  38.      */
  39.     var $_autoGrow = true;
  40.  
  41.     /**
  42.      * Value to insert into empty cells
  43.      * @var    string
  44.      * @access private
  45.      */
  46.     var $_autoFill = " ";
  47.  
  48.     /**
  49.      * Array containing the table structure
  50.      * @var     array
  51.      * @access  private
  52.      */
  53.     var $_structure = array();
  54.  
  55.     /**
  56.      * Number of rows composing in the table
  57.      * @var     int
  58.      * @access  private
  59.      */
  60.     var $_rows = 0;
  61.  
  62.     /**
  63.      * Number of column composing the table
  64.      * @var     int
  65.      * @access  private
  66.      */
  67.     var $_cols = 0;
  68.  
  69.     /**
  70.      * Tracks the level of nested tables
  71.      * @var    int
  72.      * @access private
  73.      */
  74.     var $_nestLevel = 0;
  75.  
  76.     /**
  77.      * Class constructor
  78.      * @param    array    $attributes        Associative array of table tag attributes
  79.      * @param    int      $tabOffset
  80.      * @access   public
  81.      */
  82.     function HTML_Table($attributes = null, $tabOffset = 0)
  83.     {
  84.         $commonVersion = 1.7;
  85.         if (HTML_Common::apiVersion() < $commonVersion) {
  86.             return PEAR::raiseError("HTML_Table version " . $this->apiVersion() . " requires " .
  87.                 "HTML_Common version $commonVersion or greater.", 0, PEAR_ERROR_TRIGGER);
  88.         }
  89.         HTML_Common::HTML_Common($attributes, $tabOffset);
  90.     } // end constructor
  91.  
  92.     /**
  93.      * Returns the API version
  94.      * @access  public
  95.      * @return  double
  96.      */
  97.     function apiVersion()
  98.     {
  99.         return 1.7;
  100.     } // end func apiVersion
  101.  
  102.     /**
  103.      * Sets the table caption
  104.      * @param   string    $caption
  105.      * @param   mixed     $attributes        Associative array or string of table row attributes
  106.      * @access  public
  107.      */
  108.     function setCaption($caption, $attributes = null)
  109.     {
  110.         $attributes = $this->_parseAttributes($attributes);
  111.         $this->_structure["caption"] = array("attr" => $attributes, "contents" => $caption);
  112.     } // end func setCaption
  113.  
  114.     /**
  115.      * Sets the autoFill value
  116.      * @param   mixed   $fill
  117.      * @access  public
  118.      */
  119.     function setAutoFill($fill)
  120.     {
  121.         $this->_autoFill = $fill;
  122.     } // end func setAutoFill
  123.  
  124.     /**
  125.      * Returns the autoFill value
  126.      * @access   public
  127.      * @return   mixed
  128.      */
  129.     function getAutoFill()
  130.     {
  131.         return $this->_autoFill;
  132.     } // end func getAutoFill
  133.  
  134.     /**
  135.      * Sets the autoGrow value
  136.      * @param    bool   $fill
  137.      * @access   public
  138.      */
  139.     function setAutoGrow($grow)
  140.     {
  141.         $this->_autoGrow = $grow;
  142.     } // end func setAutoGrow
  143.  
  144.     /**
  145.      * Returns the autoGrow value
  146.      * @access   public
  147.      * @return   mixed
  148.      */
  149.     function getAutoGrow()
  150.     {
  151.         return $this->_autoGrow;
  152.     } // end func getAutoGrow
  153.  
  154.     /**
  155.      * Sets the number of rows in the table
  156.      * @param    int     $rows
  157.      * @access   public
  158.      */
  159.     function setRowCount($rows)
  160.     {
  161.         $this->_rows = $rows;
  162.     } // end func setRowCount
  163.  
  164.     /**
  165.      * Sets the number of columns in the table
  166.      * @param    int     $cols
  167.      * @access   public
  168.      */
  169.     function setColCount($cols)
  170.     {
  171.         $this->_cols = $cols;
  172.     } // end func setColCount
  173.  
  174.     /**
  175.      * Returns the number of rows in the table
  176.      * @access   public
  177.      * @return   int
  178.      */
  179.     function getRowCount()
  180.     {
  181.         return $this->_rows;
  182.     } // end func getRowCount
  183.  
  184.     /**
  185.      * Sets the number of columns in the table
  186.      * @access   public
  187.      * @return   int
  188.      */
  189.     function getColCount()
  190.     {
  191.         return $this->_cols;
  192.     } // end func getColCount
  193.  
  194.     /**
  195.      * Sets a rows type 'TH' or 'TD'
  196.      * @param    int         $row    Row index
  197.      * @param    string      $type   'TH' or 'TD'
  198.      * @access   public
  199.      */
  200.  
  201.     function setRowType($row, $type)
  202.     {
  203.         for ($counter = 0; $counter < $this->_cols; $counter++) {
  204.             $this->_structure[$row][$counter]["type"] = $type;
  205.         }
  206.     } // end func setRowType
  207.  
  208.     /**
  209.      * Sets a columns type 'TH' or 'TD'
  210.      * @param    int         $col    Column index
  211.      * @param    string      $type   'TH' or 'TD'
  212.      * @access   public
  213.      */
  214.     function setColType($col, $type)
  215.     {
  216.         for ($counter = 0; $counter < $this->_rows; $counter++) {
  217.             $this->_structure[$counter][$col]["type"] = $type;
  218.         }
  219.     } // end func setColType
  220.  
  221.     /**
  222.      * Sets the cell attributes for an existing cell.
  223.      *
  224.      * If the given indices do not exist and autoGrow is true then the given
  225.      * row and/or col is automatically added.  If autoGrow is false then an
  226.      * error is returned.
  227.      * @param    int        $row         Row index
  228.      * @param    int        $col         Column index
  229.      * @param    mixed      $attributes  Associative array or string of table row attributes
  230.      * @access   public
  231.      * @throws   PEAR_Error
  232.      */
  233.     function setCellAttributes($row, $col, $attributes)
  234.     {
  235.         if (isset($this->_structure[$row][$col]) && $this->_structure[$row][$col] == "__SPANNED__") return;
  236.         $attributes = $this->_parseAttributes($attributes);
  237.         $err = $this->_adjustEnds($row, $col, 'setCellAttributes', $attributes);
  238.         if (PEAR::isError($err)) {
  239.             return $err;
  240.         }
  241.         $this->_structure[$row][$col]["attr"] = $attributes;
  242.         $this->_updateSpanGrid($row, $col);
  243.     } // end func setCellAttributes
  244.  
  245.     /**
  246.      * Updates the cell attributes passed but leaves other existing attributes in tact
  247.      * @param    int     $row         Row index
  248.      * @param    int     $col         Column index
  249.      * @param    mixed   $attributes  Associative array or string of table row attributes
  250.      * @access   public
  251.      */
  252.     function updateCellAttributes($row, $col, $attributes)
  253.     {
  254.         if (isset($this->_structure[$row][$col]) && $this->_structure[$row][$col] == "__SPANNED__") return;
  255.         $attributes = $this->_parseAttributes($attributes);
  256.         $err = $this->_adjustEnds($row, $col, 'updateCellAttributes', $attributes);
  257.         if (PEAR::isError($err)) {
  258.             return $err;
  259.         }
  260.         $this->_updateAttrArray($this->_structure[$row][$col]["attr"], $attributes);
  261.         $this->_updateSpanGrid($row, $col);
  262.     } // end func updateCellAttributes
  263.  
  264.     /**
  265.      * Returns the attributes for a given cell
  266.      * @param    int     $row         Row index
  267.      * @param    int     $col         Column index
  268.      * @return   array
  269.      * @access   public
  270.      */
  271.     function getCellAttributes($row, $col)
  272.     {
  273.         if (isset($this->_structure[$row][$col]) && $this->_structure[$row][$col] != '__SPANNED__') {
  274.             return $this->_structure[$row][$col]['attr'];
  275.         } elseif (!isset($this->_structure[$row][$col])) {
  276.             return PEAR::raiseError('Invalid table cell reference[' .
  277.                 $row . '][' . $col . '] in HTML_Table::getCellAttributes');
  278.         }
  279.         return;
  280.     } // end func getCellAttributes
  281.  
  282.     /**
  283.      * Sets the cell contents for an existing cell
  284.      *
  285.      * If the given indices do not exist and autoGrow is true then the given
  286.      * row and/or col is automatically added.  If autoGrow is false then an
  287.      * error is returned.
  288.      * @param    int      $row        Row index
  289.      * @param    int      $col        Column index
  290.      * @param    mixed    $contents   May contain html or any object with a toHTML method
  291.      * @param    string   $type       (optional) Cell type either 'TH' or 'TD'
  292.      * @access   public
  293.      * @throws   PEAR_Error
  294.      */
  295.     function setCellContents($row, $col, $contents, $type = 'TD')
  296.     {
  297.         if(isset($this->_structure[$row][$col]) && $this->_structure[$row][$col] == "__SPANNED__") return;
  298.         $err = $this->_adjustEnds($row, $col, 'setCellContents');
  299.         if (PEAR::isError($err)) {
  300.             return $err;
  301.         }
  302.         $this->_structure[$row][$col]['contents'] = $contents;
  303.         $this->_structure[$row][$col]['type'] = $type;
  304.     } // end func setCellContents
  305.  
  306.     /**
  307.      * Returns the cell contents for an existing cell
  308.      * @param    int        $row    Row index
  309.      * @param    int        $col    Column index
  310.      * @access   public
  311.      * @return   mixed
  312.      */
  313.     function getCellContents($row, $col)
  314.     {
  315.         if (isset($this->_structure[$row][$col]) && $this->_structure[$row][$col] == "__SPANNED__") return;
  316.         return $this->_structure[$row][$col]["contents"];
  317.     } // end func getCellContents
  318.  
  319.     /**
  320.      * Sets the contents of a header cell
  321.      * @param    int     $row
  322.      * @param    int     $col
  323.      * @param    mixed   $contents
  324.      * @access   public
  325.      */
  326.     function setHeaderContents($row, $col, $contents)
  327.     {
  328.         $this->setCellContents($row, $col, $contents, 'TH');
  329.     } // end func setHeaderContents
  330.  
  331.     /**
  332.      * Adds a table row and returns the row identifier
  333.      * @param    array    $contents   (optional) Must be a indexed array of valid cell contents
  334.      * @param    mixed    $attributes (optional) Associative array or string of table row attributes
  335.      *                                This can also be an array of attributes, in which case the attributes
  336.      *                                will be repeated in a loop.
  337.      * @param    string   $type       (optional) Cell type either 'TH' or 'TD'
  338.      * @param    bool     $inTR           false if attributes are to be applied in TD tags
  339.      *                                    true if attributes are to be applied in TR tag
  340.      * @return   int
  341.      * @access   public
  342.      */
  343.     function addRow($contents = null, $attributes = null, $type = 'TD', $inTR = false)
  344.     {
  345.         if (isset($contents) && !is_array($contents)) {
  346.             return PEAR::raiseError("First parameter to HTML_Table::addRow must be an array");
  347.         }
  348.         $row = $this->_rows++;
  349.         for ($counter = 0; $counter < count($contents); $counter++) {
  350.             if ($type == 'TD') {
  351.                 $this->setCellContents($row, $counter, $contents[$counter]);
  352.             } elseif ($type == 'TH') {
  353.                 $this->setHeaderContents($row, $counter, $contents[$counter]);
  354.             }
  355.         }
  356.         $this->setRowAttributes($row, $attributes, $inTR);
  357.         return $row;
  358.     } // end func addRow
  359.  
  360.     /**
  361.      * Sets the row attributes for an existing row
  362.      * @param    int      $row            Row index
  363.      * @param    mixed    $attributes     Associative array or string of table row attributes
  364.      *                                    This can also be an array of attributes, in which case the attributes
  365.      *                                    will be repeated in a loop.
  366.      * @param    bool     $inTR           false if attributes are to be applied in TD tags
  367.      *                                    true if attributes are to be applied in TR tag
  368.      * @access   public
  369.      * @throws   PEAR_Error
  370.      */
  371.     function setRowAttributes($row, $attributes, $inTR = false)
  372.     {
  373.         $multiAttr = $this->_isAttributesArray($attributes);
  374.         if (!$inTR) {
  375.             for ($i = 0; $i < $this->_cols; $i++) {
  376.                 if ($multiAttr) {
  377.                     $this->setCellAttributes($row, $i,
  378.                         $attributes[$i - ((ceil(($i+1) / count($attributes)))-1) * count($attributes)]);
  379.                 } else {
  380.                     $this->setCellAttributes($row, $i, $attributes);
  381.                 }
  382.             }
  383.         } else {
  384.             $attributes = $this->_parseAttributes($attributes);
  385.             $err = $this->_adjustEnds($row, 1, 'setRowAttributes', $attributes);
  386.             if (PEAR::isError($err)) {
  387.                 return $err;
  388.             }
  389.             $this->_structure[$row]['attr'] = $attributes;
  390.         }
  391.     } // end func setRowAttributes
  392.  
  393.     /**
  394.      * Updates the row attributes for an existing row
  395.      * @param    int      $row            Row index
  396.      * @param    mixed    $attributes     Associative array or string of table row attributes
  397.      * @param    bool     $inTR           false if attributes are to be applied in TD tags
  398.      *                                    true if attributes are to be applied in TR tag
  399.      * @access   public
  400.      * @throws   PEAR_Error
  401.      */
  402.     function updateRowAttributes($row, $attributes = null, $inTR = false)
  403.     {
  404.         $multiAttr = $this->_isAttributesArray($attributes);
  405.         if (!$inTR) {
  406.             for ($i = 0; $i < $this->_cols; $i++) {
  407.                 if ($multiAttr) {
  408.                     $this->updateCellAttributes($row, $i,
  409.                         $attributes[$i - ((ceil(($i+1) / count($attributes)))-1) * count($attributes)]);
  410.                 } else {
  411.                     $this->updateCellAttributes($row, $i, $attributes);
  412.                 }
  413.             }
  414.         } else {
  415.             $attributes = $this->_parseAttributes($attributes);
  416.             $err = $this->_adjustEnds($row, 1, 'updateRowAttributes', $attributes);
  417.             if (PEAR::isError($err)) {
  418.                 return $err;
  419.             }
  420.             $this->_updateAttrArray($this->_structure[$row]['attr'], $attributes);
  421.         }
  422.     } // end func updateRowAttributes
  423.  
  424.     /**
  425.      * Returns the attributes for a given row as contained in the TR tag
  426.      * @param    int     $row         Row index
  427.      * @return   array
  428.      * @access   public
  429.      */
  430.     function getRowAttributes($row)
  431.     {
  432.         if (isset($this->_structure[$row]['attr'])) {
  433.             return $this->_structure[$row]['attr'];
  434.         }
  435.         return;
  436.     } // end func getRowAttributes
  437.  
  438.     /**
  439.      * Alternates the row attributes starting at $start
  440.      * @param    int      $start          Row index of row in which alternating begins
  441.      * @param    mixed    $attributes1    Associative array or string of table row attributes
  442.      * @param    mixed    $attributes2    Associative array or string of table row attributes
  443.      * @param    bool     $inTR           false if attributes are to be applied in TD tags
  444.      *                                    true if attributes are to be applied in TR tag
  445.      * @access   public
  446.      */
  447.     function altRowAttributes($start, $attributes1, $attributes2, $inTR = false)
  448.     {
  449.         for ($row = $start ; $row < $this->_rows ; $row++) {
  450.             $attributes = ( ($row+$start)%2 == 0 ) ? $attributes1 : $attributes2;
  451.             $this->updateRowAttributes($row, $attributes, $inTR);
  452.         }
  453.     } // end func altRowAttributes
  454.  
  455.     /**
  456.      * Adds a table column and returns the column identifier
  457.      * @param    array    $contents   (optional) Must be a indexed array of valid cell contents
  458.      * @param    mixed    $attributes (optional) Associative array or string of table row attributes
  459.      * @param    string   $type       (optional) Cell type either 'TH' or 'TD'
  460.      * @return   int
  461.      * @access   public
  462.      */
  463.     function addCol($contents = null, $attributes = null, $type = 'TD')
  464.     {
  465.         if (isset($contents) && !is_array($contents)) {
  466.             return PEAR::raiseError("First parameter to HTML_Table::addCol must be an array");
  467.         }
  468.         $col = $this->_cols++;
  469.         for ($counter = 0; $counter < count($contents); $counter++) {
  470.             $this->setCellContents($counter, $col, $contents[$counter], $type);
  471.         }
  472.         $this->setColAttributes($col, $attributes);
  473.         return $col;
  474.     } // end func addCol
  475.  
  476.     /**
  477.      * Sets the column attributes for an existing column
  478.      * @param    int      $col            Column index
  479.      * @param    mixed    $attributes     (optional) Associative array or string of table row attributes
  480.      * @access   public
  481.      */
  482.     function setColAttributes($col, $attributes = null)
  483.     {
  484.         $multiAttr = $this->_isAttributesArray($attributes);
  485.         for ($i = 0; $i < $this->_rows; $i++) {
  486.             if ($multiAttr) {
  487.                 $this->setCellAttributes($i, $col,
  488.                     $attributes[$i - ((ceil(($i+1) / count($attributes)))-1) * count($attributes)]);
  489.             } else {
  490.                 $this->setCellAttributes($i, $col, $attributes);
  491.             }
  492.         }
  493.     } // end func setColAttributes
  494.  
  495.     /**
  496.      * Updates the column attributes for an existing column
  497.      * @param    int      $col            Column index
  498.      * @param    mixed    $attributes     (optional) Associative array or string of table row attributes
  499.      * @access   public
  500.      */
  501.     function updateColAttributes($col, $attributes = null)
  502.     {
  503.         $multiAttr = $this->_isAttributesArray($attributes);
  504.         for ($i = 0; $i < $this->_rows; $i++) {
  505.             if ($multiAttr) {
  506.                 $this->updateCellAttributes($i, $col,
  507.                     $attributes[$i - ((ceil(($i+1) / count($attributes)))-1) * count($attributes)]);
  508.             } else {
  509.                 $this->updateCellAttributes($i, $col, $attributes);
  510.             }
  511.         }
  512.     } // end func updateColAttributes
  513.  
  514.     /**
  515.      * Sets the attributes for all cells
  516.      * @param    mixed    $attributes        (optional) Associative array or string of table row attributes
  517.      * @access   public
  518.      */
  519.     function setAllAttributes($attributes = null)
  520.     {
  521.         for ($i = 0; $i < $this->_rows; $i++) {
  522.             $this->setRowAttributes($i, $attributes);
  523.         }
  524.     } // end func setAllAttributes
  525.  
  526.     /**
  527.      * Updates the attributes for all cells
  528.      * @param    mixed    $attributes        (optional) Associative array or string of table row attributes
  529.      * @access   public
  530.      */
  531.     function updateAllAttributes($attributes = null)
  532.     {
  533.         for ($i = 0; $i < $this->_rows; $i++) {
  534.             $this->updateRowAttributes($i, $attributes);
  535.         }
  536.     } // end func updateAllAttributes
  537.  
  538.     /**
  539.      * Returns the table structure as HTML
  540.      * @access  public
  541.      * @return  string
  542.      */
  543.     function toHtml()
  544.     {
  545.         $strHtml = '';
  546.         $tabs = $this->_getTabs();
  547.         $tab = $this->_getTab();
  548.         $lnEnd = $this->_getLineEnd();
  549.         if ($this->_comment) {
  550.             $strHtml .= $tabs . "<!-- $this->_comment -->" . $lnEnd;
  551.         }
  552.         $strHtml .=
  553.             $tabs . "<table" . $this->_getAttrString($this->_attributes) . ">" . $lnEnd;
  554.         if (!empty($this->_structure["caption"])) {
  555.             $attr = $this->_structure["caption"]["attr"];
  556.             $contents = $this->_structure["caption"]["contents"];
  557.             $strHtml .= $tabs . $tab . "<caption" . $this->_getAttrString($attr) . ">";
  558.             if (is_array($contents)) $contents = implode(", ", $contents);
  559.             $strHtml .= $contents;
  560.             $strHtml .= "</caption>" . $lnEnd;
  561.         }
  562.         for ($i = 0 ; $i < $this->_rows ; $i++) {
  563.             if (isset($this->_structure[$i]['attr'])) {
  564.                 $strHtml .= $tabs . $tab . "<tr".$this->_getAttrString($this->_structure[$i]['attr']).">" . $lnEnd;
  565.             } else {
  566.                 $strHtml .= $tabs .$tab . "<tr>" . $lnEnd;
  567.             }
  568.             for ($j = 0 ; $j < $this->_cols ; $j++) {
  569.                 if (isset($this -> _structure[$i][$j]) && $this->_structure[$i][$j] == "__SPANNED__") {
  570.                     $strHtml .= $tabs . $tab . $tab ."<!-- span -->" . $lnEnd;
  571.                     continue;
  572.                 }
  573.                 if (isset($this->_structure[$i][$j]["type"])) {
  574.                     $type = (strtoupper($this->_structure[$i][$j]["type"]) == "TH" ? "th" : "td");
  575.                 } else {
  576.                     $type = "td";
  577.                 }
  578.                 if (isset($this->_structure[$i][$j]["attr"])) {
  579.                     $attr = $this->_structure[$i][$j]["attr"];
  580.                 } else {
  581.                     $attr = "";
  582.                 }
  583.                 if (isset($this->_structure[$i][$j]["contents"])) {
  584.                     $contents = $this->_structure[$i][$j]["contents"];
  585.                 } else {
  586.                     $contents = "";
  587.                 }
  588.                 $strHtml .= $tabs . $tab . $tab . "<$type" . $this->_getAttrString($attr) . ">";
  589.                 if (is_object($contents)) {
  590.                     // changes indent and line end settings on nested tables
  591.                     if (is_subclass_of($contents, "html_common")) {
  592.                         $contents->setTab($tab);
  593.                         $contents->setTabOffset($this->_tabOffset + 3);
  594.                         $contents->_nestLevel = $this->_nestLevel + 1;
  595.                         $contents->setLineEnd($this->_getLineEnd());
  596.                     }
  597.                     if (method_exists($contents, "toHtml")) {
  598.                         $contents = $contents->toHtml();
  599.                     } elseif (method_exists($contents, "toString")) {
  600.                         $contents = $contents->toString();
  601.                     }
  602.                 }
  603.                 if (is_array($contents)) {
  604.                     $contents = implode(", ",$contents);
  605.                 }
  606.                 if (isset($this->_autoFill) && $contents == "") {
  607.                     $contents = $this->_autoFill;
  608.                 }
  609.                 $strHtml .= $contents;
  610.                 $strHtml .= "</$type>" . $lnEnd;
  611.             }
  612.             $strHtml .= $tabs . $tab . "</tr>" . $lnEnd;
  613.         }
  614.         $strHtml .= $tabs . "</table>" . $lnEnd;
  615.         return $strHtml;
  616.     } // end func toHtml
  617.  
  618.     /**
  619.      * Checks if rows or columns are spanned
  620.      * @param    int        $row            Row index
  621.      * @param    int        $col            Column index
  622.      * @access   private
  623.      */
  624.     function _updateSpanGrid($row, $col)
  625.     {
  626.         if (isset($this->_structure[$row][$col]["attr"]["colspan"])) {
  627.             $colspan = $this->_structure[$row][$col]["attr"]["colspan"];
  628.         }
  629.         if (isset($this->_structure[$row][$col]["attr"]["rowspan"])) {
  630.             $rowspan = $this->_structure[$row][$col]["attr"]["rowspan"];
  631.         }
  632.         if (isset($colspan)) {
  633.             for ($j = $col+1; (($j < $this->_cols) && ($j <= ($col + $colspan - 1))); $j++) {
  634.                 $this->_structure[$row][$j] = "__SPANNED__";
  635.             }
  636.         }
  637.         if (isset($rowspan)) {
  638.             for ($i = $row+1; (($i < $this->_rows) && ($i <= ($row + $rowspan - 1))); $i++) {
  639.                 $this->_structure[$i][$col] = "__SPANNED__";
  640.             }
  641.         }
  642.         if (isset($colspan) && isset($rowspan)) {
  643.             for ($i = $row+1; (($i < $this->_rows) && ($i <= ($row + $rowspan - 1))); $i++) {
  644.                 for ($j = $col+1; (($j <= $this->_cols) && ($j <= ($col + $colspan - 1))); $j++) {
  645.                     $this->_structure[$i][$j] = "__SPANNED__";
  646.                 }
  647.             }
  648.         }
  649.     } // end func _updateSpanGrid
  650.  
  651.     /**
  652.     * Adjusts ends (total number of rows and columns)
  653.     * @param    int     $row        Row index
  654.     * @param    int     $col        Column index
  655.     * @param    string  $method     Method name of caller
  656.     *                               Used to populate PEAR_Error if thrown.
  657.     * @param    array   $attributes Assoc array of attributes
  658.     *                               Default is an empty array.
  659.     * @access   private
  660.     * @throws   PEAR_Error
  661.     */
  662.     function _adjustEnds($row, $col, $method, $attributes = array())
  663.     {
  664.         $colspan = isset($attributes['colspan']) ? $attributes['colspan'] : 1;
  665.         $rowspan = isset($attributes['rowspan']) ? $attributes['rowspan'] : 1;
  666.         if (($row + $rowspan - 1) >= $this->_rows) {
  667.             if ($this->_autoGrow) {
  668.                 $this->_rows = $row + $rowspan;
  669.             } else {
  670.                 return PEAR::raiseError('Invalid table row reference[' .
  671.                     $row . '] in HTML_Table::' . $method);
  672.             }
  673.         }
  674.         if (($col + $colspan - 1) >= $this->_cols) {
  675.             if ($this->_autoGrow) {
  676.                 $this->_cols = $col + $colspan;
  677.             } else {
  678.                 return PEAR::raiseError('Invalid table column reference[' .
  679.                     $col . '] in HTML_Table::' . $method);
  680.             }
  681.         }
  682.     } // end func _adjustEnds
  683.  
  684.     /**
  685.     * Tells if the parameter is an array of attribute arrays/strings
  686.     * @param    mixed   $attributes Variable to test
  687.     * @access   private
  688.     * @return   bool
  689.     */
  690.     function _isAttributesArray($attributes)
  691.     {
  692.         if (is_array($attributes) && isset($attributes[0])) {
  693.             if (is_array($attributes[0]) || (is_string($attributes[0]) && count($attributes) > 1)) {
  694.                 return true;
  695.             }
  696.         }
  697.         return false;
  698.     } // end func _isAttributesArray
  699. } // end class HTML_Table
  700. ?>